import os
from datetime import datetime, timedelta, date

from flask import request, session, redirect, url_for, render_template, jsonify, current_app, g, abort

from info import db
from info.common import user_login_data
from info.constants import ADMIN_USER_PAGE_MAX_COUNT
from info.models import User, News, Category
from info.modules.admin import admin_blue
from info.response_code import RET, error_map
import time
# 1.后台登录，首页，退出 123
# 2.用户统计，用户列表 45
# 3.显示新闻审核列表，审核新闻详情，提交审核 678
# 4.显示新闻版式编辑列表，显示新闻版式详情，提交新闻编辑 91011
# 5.新增/修改新闻分类 12


# 1.后台登录
@admin_blue.route("/login",methods=["GET","POST"])
def login():
    if request.method == "GET":
        is_admin = session.get("is_admin")
        user_id = session.get("user_id")
        if is_admin and user_id:
            return redirect(url_for("admin.index"))
        return render_template("admin/login.html")
    username = request.form.get("username")
    password = request.form.get("password")
    if not all([username, password]):
        return render_template("admin/login.html",errmsg="参数不完整")
    # 拿到用户模型
    try:
        user = User.query.filter(User.mobile==username,User.is_admin==True).first()
    except BaseException as e:
        current_app.logger.error(e)
        return render_template("admin/login.html",errmsg="数据库问题")
    if not user:
        return render_template("admin/login.html",errmsg="管理员不存在")
    if not user.check_password(password):
        return render_template("admin/login.html",errmsg="密码错误")
    # 状态保存
    session["user_id"] = user.id
    session["is_admin"] = True
    return redirect(url_for("admin.index"))


# 2.后台首页
@admin_blue.route("/index")
@user_login_data
def index():
    return render_template("admin/index.html",user=g.user.to_dict())


# 3.后台退出
@admin_blue.route("/logout")
def logout():
    session.pop("is_admin",None)
    session.pop("user_id",None)
    return render_template("admin/login.html")


# 4.用户统计
@admin_blue.route("/user_count")
def user_count():
    # 总用户数 月增 日增 近三十天用户新增数据
    # 1.总用户数
    total_count = 0
    try:
        total_count = User.query.filter(User.is_admin != True).count()
    except BaseException as e:
        current_app.logger.error(e)
    # 2.月增用户数量
    mon_count = 0
    t = time.localtime()
    date_day_str = "%d-%02d-01"% (t.tm_year,t.tm_mon)
    date_day = datetime.strptime(date_day_str,"%Y-%m-%d")
    try:
        mon_count = User.query.filter(User.is_admin!=True, User.create_time>=date_day).count()
    except BaseException as e:
        current_app.logger.error(e)
    # 3.日增用户
    day_count = 0
    data_day_str = "%d-%02d-%02d"% (t.tm_year,t.tm_mon,t.tm_mday)
    data_day = datetime.strptime(data_day_str,"%Y-%m-%d")
    try:
        day_count = User.query.filter(User.is_admin != True,User.create_time>=data_day).count()
    except BaseException as e:
        current_app.logger.error(e)

    # 4.近一个月新增人数情况
    active_count = []
    active_time = []
    for i in range(0,30):
        begin_day = data_day - timedelta(days=i)
        end_day = date_day + timedelta(days=1-i)
        try:
            one_day_count = User.query.filter(User.is_admin != True,User.create_time>=begin_day,User.create_time<=end_day).count()
            active_count.append(one_day_count)
            one_day_str = begin_day.strftime("%Y-%m-%d")
            active_time.append(one_day_str)
        except BaseException as e:
            current_app.logger.error(e)
    active_count.reverse()
    active_time.reverse()
    data = {
        "total_count": total_count,
        "mon_count": mon_count,
        "day_count": day_count,
        "active_count": active_count,
        "active_time": active_time,

    }
    return render_template("admin/user_count.html",data=data)


# 5.用户列表
@admin_blue.route("/user_list")
def user_list():
    p = request.args.get("p", 1)
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
    user_list = []
    cur_page = 1
    total_page = 1
    try:
        pn = User.query.filter(User.is_admin!=True).paginate(page=p,per_page=ADMIN_USER_PAGE_MAX_COUNT)
        user_list = [user.to_admin_dict() for user in pn.items]
        cur_page = pn.page
        total_page = pn.pages
    except BaseException as e:
        current_app.logger.error(e)
    data={
        "user_list":user_list,
        "cur_page":cur_page,
        "total_page":total_page
    }
    return render_template("admin/user_list.html",data=data)


# 6.显示审核新闻列表
@admin_blue.route("/news_review")
def news_review():
    p = request.args.get("p",1)
    keyword = request.args.get("keyword")
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
    filter_list = []
    if keyword:
        filter_list.append(News.title.contains(keyword))
    news_list=[]
    cur_page = 1
    total_page=1
    try:
        pn = News.query.filter(*filter_list).order_by(News.create_time.desc()).paginate(page=p,per_page=ADMIN_USER_PAGE_MAX_COUNT)
        news_list = [news.to_review_dict() for news in pn.items]
        cur_page = pn.page
        total_page = pn.pages
    except BaseException as e:
        current_app.logger.error(e)

    data = {
        "news_list":news_list,
        "cur_page":cur_page,
        "total_page":total_page
    }

    return render_template("admin/news_review.html",data=data)


# 7.显示审核新闻列表详情
@admin_blue.route("/news_review_detail/<int:news_id>")
def news_review_detail(news_id):
    try:
        news = News.query.get(news_id)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(404)
    if not news:
        return abort(404)
    return render_template("admin/news_review_detail.html",news = news.to_dict())


# 8.审核新闻
@admin_blue.route("/news_review_action",methods=["POST"])
def news_review_action():
    action = request.json.get("action")
    news_id = request.json.get("news_id")
    reason = request.json.get("reason")
    if not all([action,news_id]):
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    if action not in ["accept","reject"]:
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    try:
        news_id = int(news_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    try:
        news = News.query.get(news_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg=error_map[RET.DBERR])
    if not news:
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    if action == "accept":
        news.status = 0
    if action == "reject":
        news.status = 1
        if not reason:
            return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
        news.reason = reason
    return jsonify(errno=RET.OK,errmsg=error_map[RET.OK])


# 9.新闻列表
@admin_blue.route("/news_edit")
def news_edit():
    p = request.args.get("p", 1)
    keyword = request.args.get("keyword")
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(403)
    filter_list = []
    if keyword:
        filter_list.append(News.title.contains(keyword))
    news_list = []
    cur_page = 1
    total_page = 1
    try:
        pn = News.query.filter(*filter_list).order_by(News.create_time.desc()).paginate(page=p,per_page=ADMIN_USER_PAGE_MAX_COUNT)
        news_list = [news.to_dict() for news in pn.items]
        cur_page = pn.page
        total_page = pn.pages
    except BaseException as e:
        current_app.logger.error(e)
        return abort(403)
    data = {
        "news_list":news_list,
        "cur_page":cur_page,
        "total_page":total_page
    }
    return render_template("admin/news_edit.html",data=data)


# 10.新闻详情显示
@admin_blue.route("/news_edit_detail/<int:news_id>")
def news_edit_detail(news_id):
    try:
       news =  News.query.get(news_id)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(403)
    if not news:
        return abort(403)
    try:
        categories = Category.query.all()
    except BaseException as e:
        return abort(403)
    category_list = []
    for category in categories:
        is_selected = False
        category_dict = category.to_dict()
        if category.id == news.id:
            is_selected = True
        category_dict["is_selected"] = is_selected
        category_list.append(category_dict)
    return render_template("admin/news_edit_detail.html",news = news.to_dict(),category_list = category_list)


# 11.新闻详情编辑
@admin_blue.route("/news_edit_detail",methods=["POST"])
def news_edit_action():
    news_id = request.form.get("news_id")
    category_id = request.form.get("category_id")
    title = request.form.get("title")
    digest = request.form.get("digest")
    content = request.form.get("content")
    index_image = request.files.get("index_image")
    if not all([news_id,category_id,title,digest,content]):
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    try:
        news_id = int(news_id)
        category_id = int(category_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    try:
        news = News.query.get(news_id)
        category = Category.query.get(category_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg=error_map[RET.DBERR])
    if not news or not category:
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    news.title = title
    news.digest = digest
    news.content = content
    news.category_id = category_id
    if index_image:
        image_bytes = index_image.read()
        try:
            local_filename = os.path.join(current_app.static_folder, 'picture',
                                          date.strftime(datetime.now(), "%d:%m:%Y:%H:%M:%S") + ".jpg")
            with open(local_filename, 'wb') as f:
                f.write(image_bytes)
            news.index_image_url = 'picture/' + date.strftime(datetime.now(), "%d:%m:%Y:%H:%M:%S") + ".jpg"
        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.PARAMERR, errmsg="写入图片出错")
    return jsonify(errno=RET.OK,errmsg=error_map[RET.OK])


# 12.新增/修改分类
@admin_blue.route("/news_type",methods=["GET","POST"])
def news_type():
    # 展示
    if request.method == "GET":
        try:
            categories = Category.query.all()
        except BaseException as e:
            current_app.logger.error(e)
            return abort(403)
        return render_template("admin/news_type.html",categories=categories)
    # 新增修改
    id = request.json.get("id")
    name = request.json.get("name")
    if not name:
        return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
    if id:
        try:
            id = int(id)
        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
        try:
            category = Category.query.get(id)
        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg=error_map[RET.DBERR])
        if not category:
            return jsonify(errno=RET.PARAMERR,errmsg=error_map[RET.PARAMERR])
        category.name = name
    else:
        category = Category()
        category.name = name
        db.session.add(category)
    return jsonify(errno=RET.OK,errmsg=error_map[RET.OK])


